package requeteur.ejb.dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.sql.DataSource;

import requeteur.ejb.commun.dto.Champ;
import requeteur.ejb.commun.dto.CleEtrangere;
import requeteur.ejb.commun.dto.Driver;
import requeteur.ejb.commun.dto.InformationBaseDeDonnees;
import requeteur.ejb.commun.dto.InformationConnection;
import requeteur.ejb.commun.dto.Session;
import requeteur.ejb.commun.dto.Table;
import requeteur.ejb.commun.exception.ConnectionException;
import requeteur.ejb.commun.outil.ConnectionUtils;
import requeteur.ejb.commun.outil.RequeteurUtils;

/**
 * @author Laurent
 * @version 0.1
 */
@Stateless
public class DaoRecupererInformation {


	/**
	 * Constructeur de la classe <code>DaoRecupererInformation</code>.
	 */
	public DaoRecupererInformation() {
	}

	public InformationBaseDeDonnees getInformationBaseDeDonnees(InformationConnection informationConnection) throws ConnectionException {
		Connection vConnection = null;
		InformationBaseDeDonnees vInformationBaseDeDonnees = new InformationBaseDeDonnees();
		try {
			vConnection = RequeteurUtils.getConnection(informationConnection);
			vInformationBaseDeDonnees = new InformationBaseDeDonnees();
			vInformationBaseDeDonnees.setNom(vConnection.getMetaData().getDatabaseProductName());
			vInformationBaseDeDonnees.setVersion(vConnection.getMetaData().getDatabaseProductVersion());
			for (String vMotCleSql : vConnection.getMetaData().getSQLKeywords().split(",")) {
				vInformationBaseDeDonnees.getMotClesSql().add(vMotCleSql.trim());
			}
			for (String vDateTimeFunctions : vConnection.getMetaData().getTimeDateFunctions().split(",")) {
				vInformationBaseDeDonnees.getFonctionsDateHeure().add(vDateTimeFunctions.trim());
			}
			vInformationBaseDeDonnees.setAutoCommit(vConnection.getAutoCommit());

			// Récupération des informations sur le driver utilisé
			Driver vDriver = new Driver(vConnection.getMetaData().getDriverName(), vConnection.getMetaData().getDriverVersion());
			vInformationBaseDeDonnees.setDriver(vDriver);

			// Récupération des informations sur la session
			Session vSession = new Session();
			vSession.setUtilisateur(vConnection.getMetaData().getUserName());
			vInformationBaseDeDonnees.setSession(vSession);
		} catch (Exception e) {
			throw new ConnectionException("Erreur lors de la récupération des informations sur les bases de données", e);
		} finally {
			ConnectionUtils.fermerConnexion(vConnection);
		}
		return vInformationBaseDeDonnees;
	}

	/**
	 * @param pBaseDeDonnees
	 * @return
	 * @throws ConnectionException
	 */
	public List<Table> listerTables(InformationConnection informationConnection) throws ConnectionException {
		Connection vConnection = null;
		List<Table> vTables = new ArrayList<Table>();
		try {
			vConnection = RequeteurUtils.getConnection(informationConnection);
			// Récupération des différentes tables de la base sélectionnée
			ResultSet vResultTables = null;
			if (vConnection.getCatalog() != null) {
				vResultTables = vConnection.getMetaData().getTables(vConnection.getCatalog(), null, null, null);
			} else {
				vResultTables = vConnection.getMetaData().getTables(null, vConnection.getMetaData().getUserName(), null, null);
			}
			while (vResultTables.next()) {
				vTables.add(new Table(vResultTables));
			}
		} catch (Exception e) {
			throw new ConnectionException("Erreur lors de la récupération des informations des tables de la base de données", e);
		} finally {
			ConnectionUtils.fermerConnexion(vConnection);
		}
		return vTables;
	}

	public List<Champ> listerChamps(Table pTable, InformationConnection informationConnection) throws ConnectionException {
		Connection vConnection = null;
		List<Champ> vChamps = new ArrayList<Champ>();
		try {
			vConnection = RequeteurUtils.getConnection(informationConnection);
			// Récupération des différentes colonnes de la table sélectionnée
			ResultSet vResultChamps = null;
			ResultSet vConstraintsPk = null;
			ResultSet vConstraintsFk = null;
			if (vConnection.getCatalog() != null) {
				vResultChamps = vConnection.getMetaData().getColumns(vConnection.getCatalog(), null, pTable.getNom(), null);
				vConstraintsPk = vConnection.getMetaData().getPrimaryKeys(vConnection.getCatalog(), null, pTable.getNom());
				vConstraintsFk = vConnection.getMetaData().getImportedKeys(vConnection.getCatalog(), null, pTable.getNom());
			} else {
				vResultChamps = vConnection.getMetaData().getColumns(null, vConnection.getMetaData().getUserName(), pTable.getNom(), null);
				vConstraintsPk = vConnection.getMetaData().getPrimaryKeys(null, vConnection.getCatalog(), pTable.getNom());
				vConstraintsFk = vConnection.getMetaData().getImportedKeys(null, vConnection.getCatalog(), pTable.getNom());
			}
			while (vResultChamps.next()) {
				vChamps.add(new Champ(vResultChamps));
			}
			// Récupération des clés primaires
			while (vConstraintsPk.next()) {
				String vNomChamp = vConstraintsPk.getString("COLUMN_NAME");
				for (Champ vChamp : vChamps) {
					if (vChamp.getNom().equals(vNomChamp)) {
						vChamp.setPrimary(true);
						break;
					}
				}
			}
			// Récupération des clés étrangères
			while (vConstraintsFk.next()) {
				String vNomChamp = vConstraintsFk.getString("FKCOLUMN_NAME");
				for (Champ vChamp : vChamps) {
					if (vChamp.getNom().equals(vNomChamp)) {
						vChamp.setCleEtrangere(new CleEtrangere(vConstraintsFk));
						break;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new ConnectionException("Erreur lors de la récupération des informations des champs de la table", e);
		} finally {
			ConnectionUtils.fermerConnexion(vConnection);
		}
		return vChamps;
	}
}
